Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by www.netzwerkartist.de...

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Exceptions
8 Die Funktionsbibliothek
9 Threads und nebenläufige Programmierung
10 Raum und Zeit
11 Datenstrukturen und Algorithmen
12 Dateien und Datenströme
13 Die eXtensible Markup Language (XML)
14 Grafische Oberflächen mit Swing
15 Grafikprogrammierung
16 Das Netz
17 JavaServer Pages und Servlets
18 Verteilte Programmierung mit RMI und Web–Services
19 Applets, Midlets und Sound
20 Datenbankmanagement mit JDBC
21 Reflection und Annotationen
22 Komponenten durch Bohnen
23 Logging und Monitoring
24 Sicherheitskonzepte
25 Java Native Interface (JNI)
26 Dienstprogramme für die Java-Umgebung
A Die Begleit-DVD
Index

Download:
- ZIP, ca. 12,5 MB
Buch bestellen

Website zum Buch
Weblog des Autors
Ihre Meinung?

Spacer
 <<   zurück
Java ist auch eine Insel von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel

Java ist auch eine Insel
6., akt. und erw. Aufl., mit DVD
1.454 S., 49,90 Euro
Galileo Computing
ISBN 3-89842-838-9
gp 8 Die Funktionsbibliothek
  gp 8.1 Die Java-Klassenphilosophie
    gp 8.1.1 Übersicht über die Pakete der Standardbibliothek
  gp 8.2 Wrapper-Klassen
    gp 8.2.1 Die Basisklasse Number für numerische Wrapper-Objekte
    gp 8.2.2 Die Klasse Integer
    gp 8.2.3 Unterschiedliche Ausgabeformate
    gp 8.2.4 Autoboxing: Boxing und Unboxing
    gp 8.2.5 Die Boolean-Klasse
    gp 8.2.6 Die Klassen Double und Float für Fließkommazahlen
  gp 8.3 Die Utility-Klasse System und Properties
    gp 8.3.1 Systemeigenschaften der Java-Umgebung
    gp 8.3.2 line.separator
    gp 8.3.3 Browser-Version abfragen
    gp 8.3.4 Property von der Konsole aus setzen
    gp 8.3.5 Umgebungsvariablen des Betriebssystems
    gp 8.3.6 Einfache Zeitmessung und Profiling
  gp 8.4 Benutzereinstellungen
    gp 8.4.1 Eine zentrale Registry
    gp 8.4.2 Einträge einfügen, auslesen und löschen
    gp 8.4.3 Auslesen der Daten und Schreiben in anderem Format
    gp 8.4.4 Auf Ereignisse horchen
  gp 8.5 Klassenlader (Class Loader)
    gp 8.5.1 Woher die kleinen Klassen kommen
    gp 8.5.2 Setzen des Klassenpfades
    gp 8.5.3 Die wichtigsten drei Typen von Klassenladern
    gp 8.5.4 Der java.lang.ClassLoader
    gp 8.5.5 Hot Deployment mit dem URL-ClassLoader
    gp 8.5.6 Das jre/lib/endorsed-Verzeichnis
    gp 8.5.7 getContextClassLoader() vom Thread
    gp 8.5.8 Wie heißt die Klasse mit der Methode main()?
  gp 8.6 Design-Pattern und das Beobachten von Änderungen
    gp 8.6.1 Design-Pattern
    gp 8.6.2 Das Beobachter-Pattern (Observer/Observable)
  gp 8.7 Ausführen externer Programme, Compiler und Skripten
    gp 8.7.1 ProcessBuilder und Prozesskontrolle mit Process
    gp 8.7.2 Die Windows-Registry verwenden
    gp 8.7.3 Einen Browser/E-Mail-Client/Editor aufrufen
    gp 8.7.4 Ausführen von Skripten
    gp 8.7.5 Programme mit der Compiler API übersetzen
  gp 8.8 Annotationen
    gp 8.8.1 Annotationstypen @Override, @Deprecated, @SuppressWarnings
    gp 8.8.2 Common Annotations
    gp 8.8.3 Annotationen für Web-Services
    gp 8.8.4 Annotationen für XML-Mapping
  gp 8.9 Zum Weiterlesen


Galileo Computing

8.3 Die Utility-Klasse System und Properties  downtop

In der Klasse java.lang.System finden sich Methoden zum Erfragen und Ändern von Systemvariablen, zum Umlenken der Standard-Datenströme, zum Ermitteln der aktuellen Zeit, zum Beenden der Applikation und noch das ein oder andere. Alle Methoden sind statisch, und ein Exemplar von System lässt sich nicht anlegen. In der Klasse java.lang.Runtime – die Schnittstelle RunTime aus dem CORBA-Paket hat hiermit nichts zu tun – finden sich zusätzlich Hilfsfunktionen wie das Starten von externen Programmen oder Methoden zum Erfragen des Speicherbedarfs. Anders als System ist hier nur eine Funktion statisch, nämlich die Singleton-Methode getRuntime(), die das Exemplar von Runtime liefert.

Insgesamt machen die beiden Klassen keinen besonders aufgeräumten Eindruck; sie erwecken irgendwie den Eindruck, dass hier alles zu finden ist, was an anderen Stellen nicht mehr hingepasst hat. Auch wären Funktionen einer Klasse genauso gut in der anderen Klasse aufgehoben. Dass die Methode System.arraycopy() zum Kopieren von Feldern nicht in java.-util.Arrays stationiert ist, lässt sich nur historisch erklären. Und System.exit() leitet an Runtime.getRuntime().exit() weiter. Einige Methoden sind veraltet beziehungsweise anders verteilt: das exec() von Runtime zum Starten von externen Prozessen übernimmt eine neue Klasse ProcessBuilder, und die Frage nach dem Speicherzustand oder der Anzahl an Prozessoren beantworten MBeans wie etwa ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors().


Galileo Computing

8.3.1 Systemeigenschaften der Java-Umgebung  downtop

Die Java-Umgebung verwaltet Systemeigenschaften wie Pfadtrenner oder die Version der virtuellen Maschine in einem java.util.Properties-Objekt. Die statische Funktion System.-getProperties() erfragt diese Systemeigenschaften und liefert das gefüllte Properties-Objekt zurück. Zum Erfragen einzelner Eigenschaften ist das Properties-Objekt aber nicht unbedingt nötig: System.getProperty() erfragt direkt eine Eigenschaft.


Beispiel Gib den Namen des Betriebssystems aus:
System.out.println( System.getProperty("os.name") );

Gib alle Systemeigenschaften auf dem Bildschirm aus:

System.getProperties().list( System.out );

Eine Liste der Standard-Systemeigenschaften bietet die API-Dokumentation, und die Webseite http://java-tutor.com/go/sysprops sammelt Belegungen für unterschiedliche Laufzeitumgebungen.


final class java.lang.System

  • static String getProperty( String key ) Gibt die Belegung einer Systemeigenschaft zurück. Ist der Schlüssel null oder leer, gibt es eine NullPointerException bzw. eine IllegalArgumentException.
  • static String getProperty( String key, String def ) Gibt die Belegung einer Systemeigenschaft zurück. Ist sie nicht vorhanden, liefert die Funktion die Zeichenkette def, den Default-Wert. Für die Ausnahmen gilt das Gleiche wie bei getProperty(String).
  • static String setProperty( String key, String value ) Belegt eine Systemeigenschaft neu. Die Rückgabe ist die alte Belegung – oder null, falls es keine alte Belegung gab.
  • static String clearProperty( String key ) Löscht eine Systemeigenschaft aus der Liste. Die Rückgabe ist die alte Belegung – oder null, falls es keine alte Belegung gab.
  • static Properties getProperties() Liefert ein mit den aktuellen Systembelegungen gefülltes Properties-Objekt.

Galileo Computing

8.3.2 line.separator  downtop

Um nach dem Ende einer Zeile zum Anfang der nächsten zu kommen, wird ein Zeilenumbruch (engl. new line) eingefügt. Das Zeichen für den Zeilenumbruch muss kein einzelnes sein, es können auch mehrere Zeichen nötig sein. Zum Leidwesen der Programmierer unterscheidet sich die Anzahl der Zeichen für den Zeilenumbruch auf den bekannten Architekturen:

  • Unix: Line Feed (Zeilenvorschub)
  • Macintosh: Carriage Return (Wagenrücklauf)
  • Windows: beide Zeichen (Carriage Return und Linefeed)

Der Steuercode für Carriage Return (kurz CR) ist 13 (0x0D), der für Line Feed (kurz LF) ist 10 (0x0A). Java vergibt obendrein eigene Escape-Sequenzen für diese Zeichen: \r für Carriage Return und \n für Line Feed. (Die Sequenz \f für ein Form Feed – Seitenvorschub – spielt bei den Zeilenumbrüchen keine Rolle.)

Um sich nicht in eine Abhängigkeit von einem Betriebssystem zu begeben, sollte der Zeilenumbruch vom System erfragt werden. Hierzu gibt es eine Property: line.separator. Unter Windows ergibt sich folgendes Bild:

System.out.println( System.getProperty("os.name") );             // Windows 2000 
String lineSep = System.getProperty( "line.separator" ); 
System.out.println( lineSep.length() );                          // 2 
System.out.println( Integer.toHexString(lineSep.charAt(0)) );    // d 
if ( lineSep.length() > 1 ) 
  System.out.println( Integer.toHexString(lineSep.charAt(1)) );  // a

Mit einem println() oder »%n« in format() beziehungsweise printf() haben wir auch keine Probleme.


Galileo Computing

8.3.3 Browser-Version abfragen  downtop

Nützlich für Applets sind die Eigenschaften browser.version und java.vendor. Letzteres identifiziert den Browser, und so lässt sich in Erfahrung bringen, ob der Browser ein Internet Explorer oder Netscape Communicator ist.

String prop  = System.getProperty( "java.vendor" ); 
boolean isIe = prop.indexOf( "Microsoft Corp." ) >= 0;

Galileo Computing

8.3.4 Property von der Konsole aus setzen  downtop

Eigenschaften lassen sich auch beim Programmstart von der Konsole aus setzen. Dies ist praktisch für eine Eigenschaft, die beispielsweise das Verhalten des Programms steuert oder das Programm konfiguriert. In der Kommandozeile werden mit -D der Name der Eigenschaft und ihr Wert angegeben. Viele Entwicklungsumgebungen erlauben es, diese in einem Fenster zu setzen. Die Informationen tauchen nicht bei der Argument-Liste in der main()-Methode auf, da sie vor dem Namen der Klasse stehen und bereits von der Java-Laufzeitumgebung verarbeitet werden.

Um die Eigenschaften auszulesen, gibt es zwei Möglichkeiten. Eine davon ist überraschend.

Listing 8.5    SetProperty.java

class SetProperty 
{ 
  static public void main( String[] args ) 
  { 
    boolean debug = false; 
    String prop = System.getProperty( "DEBUG" ); 
 
    // Erste Möglichkeit 
    if ( prop != null ) 
      debug = Boolean.valueOf(prop).booleanValue(); 
 
 
    if ( debug ) 
        System.out.println( "Wir dürfen debuggen" ); 
 
    // Zweite Möglichkeit 
    System.out.println( Boolean.getBoolean("DEBUG") ); 
 } 
}

Auf der Konsole erfolgt die Ausgabe:

$ java -DDEBUG=true SetProperty 
Wir dürfen debuggen 
true

Wir bekommen über getProperty() einen String zurück, der den Wert anzeigt. Falls es überhaupt keine Eigenschaft mit diesem Namen gibt, erhalten wir stattdessen null. So wissen wir auch, ob dieser Wert überhaupt gesetzt wurde.

Für die Wahrheitswerte gibt es die statische Funktion getBoolean() in der Klasse Boolean, die aus den System-Properties eine Eigenschaft mit dem angegebenen Namen heraussucht.

public static boolean getBoolean( String name ) { 
  return toBoolean( System.getProperty(name) ); 
}

Es erstaunt, diese Funktion in der Wrapper-Klasse Boolean anzutreffen, weil dies nichts mit den Wrapper-Objekten zu tun hat. Gegenüber einer eigenen, direkten System-Anfrage hat getBoolean() auch den Nachteil, dass wir bei der Rückgabe false nicht unterscheiden können, ob es die Eigenschaft nicht gibt oder ob die Eigenschaft mit dem Wert false belegt ist.


final class java.lang.Boolean 
implements Serializable, Comparable<Boolean>

  • static boolean getBoolean( String propName ) Liest eine Systemeigenschaft aus.

Galileo Computing

8.3.5 Umgebungsvariablen des Betriebssystems  downtop

Fast jedes Betriebssystem nutzt das Konzept der Umgebungsvariablen; bekannt ist etwa PATH für den Suchpfad für Applikationen unter Windows und unter Unix. Die von Java mittels System.getProperties() eingeführten Eigenschaften unterscheiden sich grundlegend von den System-Umgebungsvariablen und tauchen daher in der Liste nicht auf.

Seit Java 5 ist es möglich, auf diese System-Umgebungsvariablen zuzugreifen. Dazu dient die statische Funktion System.getenv(). Sie liefert eine Menge von <String, String>-Paaren.


Tabelle 8.4    Auswahl einiger unter Windows verfügbaren Umgebungsvariablen
Name der Variablen Beschreibung Beispiel
COMPUTERNAME Name des Computers MOE
HOMEDRIVE Laufwerksbuchstabe vom Benutzerverzeichnis C
HOMEPATH Pfad des Benutzerverzeichnisses \Dokumente und Einstellungen\Christian Ullenboom
OS Name des Betriebssystems Windows_NT
PATH Suchpfad C:\WINDOWS\system32;C:\WINDOWS
PATHEXT Dateiendungen, die für ausführbare Programme stehen .COM;.EXE;.BAT;.CMD;.WSH
SYSTEMDRIVE Laufwerksbuchstabe des Betriebssystems C
TEMP und auch TMP Temporäres Verzeichnis C:\DOKUME~1\CHRIST~1\LOKALE~1\ Temp
USERDOMAIN Domäne des Benutzers MOE
USERNAME Name des Nutzers Christian Ullenboom
USERPROFILE Profilverzeichnis C:\Dokumente und Einstellungen\ Christian Ullenboom
WINDIR Verzeichnis des Betriebssystems C:\WINDOWS

Einige der Variablen sind auch über die System-Properties zu erreichen.

Um auf eine spezielle Umgebungsvariable zuzugreifen, lässt sich getenv(String) nutzen, etwa um den Suchpfad herauszufinden: System.getenv("path");


Beispiel Gib die Umgebungsvariablen des Systems aus. Um die Ausgabe etwas übersichtlicher zu gestalten, ist bei der Aufzählung jedes Komma durch ein Zeilenvorschubzeichen ersetzt worden.
Map<String,String> map = System.getenv(); 
System.out.println( map.toString().replace(',', '\n') );


Galileo Computing

8.3.6 Einfache Zeitmessung und Profiling  toptop

Neben den komfortablen Klassen zum Verwalten von Datumswerten gibt es mit zwei Funktionen einfache Möglichkeiten, Zeiten für Programmabschnitte zu messen:


final class java.lang.System

  • static long currentTimeMillis() Gibt die seit dem 1.1.1970 vergangenen Millisekunden zurück.
  • static long nanoTime() Liefert vom genauesten System-Zeitgeber die Zeit. Sie hat keinen Bezugspunkt zu irgendeinem Datum; vom 1.1.1970 sind so viele Nanosekunden vergangen, dass sie gar nicht in den long passen würden.

Die Differenz zweier Zeitwerte kann zur groben Abschätzung von Ausführungszeiten für Programme dienen.

Listing 8.6    com/javatutor/insel/lang/Profiling.java

package com.javatutor.insel.lang; 
 
import static java.util.concurrent.TimeUnit.NANOSECONDS; 
 
class Profiling 
{ 
  private static long[] measure() 
  { 
    final int MAX = 3000; 
 
    final String string = "Aber Angie, Angie, ist es nicht an der Zeit,  
                           Goodbye zu sagen? " + 
                          "Ohne Liebe in unseren Seelen und ohne Geld in  
                           unseren Mänteln. " + 
                          "Du kannst nicht sagen, dass wir zufrieden sind."; 
 
    final int    number     = 123; 
    final double nullnummer = 0.0; 
 
    // StringBuffer(size) und append() zur Konkatenation 
 
    long time1 = System.nanoTime(); 
 
    final StringBuilder sb1 = new StringBuilder( MAX * (string.length() + 6) ); 
    for ( int i = MAX; i-- > 0; ) 
      sb1.append( string ).append( number ).append( nullnummer ); 
    sb1.toString(); 
 
    time1 = NANOSECONDS.toMillis( System.nanoTime() - time1 ); 
 
    // StringBuffer und append() zur Konkatenation 
 
    long time2 = System.nanoTime(); 
 
    final StringBuilder sb2 = new StringBuilder(); 
    for ( int i = MAX; i-- > 0; ) 
      sb2.append( string ).append( number ).append( nullnummer ); 
    sb2.toString(); 
 
    time2 = NANOSECONDS.toMillis( System.nanoTime() - time2 ); 
 
    // + zur Konkatenation 
 
    long time3 = System.nanoTime(); 
 
    String t = ""; 
    for ( int i = MAX; i-- > 0; ) 
      t += string + number + nullnummer; 
 
    time3 = NANOSECONDS.toMillis( System.nanoTime() - time3 ); 
 
    return new long[] { time1, time2, time3 }; 
  } 
 
  public static void main( String[] args ) 
  { 
    measure(); System.gc(); measure(); System.gc(); 
    long[] durations = measure(); 
 
    System.out.printf( "sb(size), append(): %d ms%n", durations[0] ); // sb(size), 
                                                                 // append(): 2 ms 
    System.out.printf( "sb(), append()    : %d ms%n", durations[1] ); // sb(), 
                                                            // append()    : 21 ms 
    System.out.printf( "t+=               : %d ms%n", durations[2] ); // t+= 
                                                                     // : 10661 ms 
  } 
}

Das Testprogramm hängt Zeichenfolgen mit

  • einem StringBuilder, der nicht in der Endgrößte initialisiert ist,
  • einen StringBuilder, der eine vorinitialisierte Endgröße nutzt, und
  • dem Plus-Operator von Strings zusammen.

Vor der Messung gibt es zwei Testläufe und ein System.gc(), was den Garbage Collector anweist, Speicher freizugeben. (Das würde in gewöhnlichen Programmen nicht stehen, da der GC schon selbst ganz gut weiß, wann Speicher freizugeben ist. Nur kostet das Freigeben auch Ausführungszeit, und es würde die Messzeiten beeinflussen, was wir hier nicht wollen.)

Auf meinem Rechner – Intel Pentium D 920 (2 Prozessoren), Java SE 6 – liefert das Programm die Ausgabe:

sb(size), append(): 3 ms 
sb(), append()    : 5 ms 
t+=               : 26948 ms

Das Ergebnis: Bei großen Anhänge-Operationen ist es ein wenig besser, einen passend in der Größe initialisierten StringBuilder zu benutzen. Über das + entstehen viele temporäre Objekte, was wirklich teuer kommt. Aber auch, wenn der StringBuilder nicht die passende Größe enthält, sind die Differenzen nahezu unbedeutend.

Wo im Programm überhaupt Taktzyklen verbraten werden, zeigt ein Profiler. An diesen Stellen kann dann mit der Optimierung begonnen werden. Eclipse sieht mit dem TPTP (http://www.eclipse.org/tptp/) eine solche Messumgebung vor.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.





 <<   zurück



Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de